package com.itwlj.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itwlj.constant.JwtClaimsConstant;
import com.itwlj.constant.MessageConstant;
import com.itwlj.constant.TypeConstant;
import com.itwlj.context.BaseContext;
import com.itwlj.dto.PasswordUpdateDTO;
import com.itwlj.dto.UserDTO;
import com.itwlj.dto.UserLoginDTO;
import com.itwlj.dto.UserPageQueryDTO;
import com.itwlj.entity.User;
import com.itwlj.exception.AccountLockedException;
import com.itwlj.exception.AccountNotFoundException;
import com.itwlj.exception.AccountOrPasswordErrorException;
import com.itwlj.exception.PasswordErrorException;
import com.itwlj.mapper.UserMapper;
import com.itwlj.properties.JwtProperties;
import com.itwlj.result.PageResult;
import com.itwlj.service.UserService;
import com.itwlj.utils.JwtUtil;
import com.itwlj.vo.UserLoginVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private JwtProperties jwtProperties;

    /**
     * 登录
     *
     * @param userLoginDTO
     * @return
     */
    public UserLoginVO login(UserLoginDTO userLoginDTO) {
        String account = userLoginDTO.getAccount();
        String password = userLoginDTO.getPassword();

        User user = userMapper.getByAccount(account, userLoginDTO.getType());

        //账号不存在
        if (user == null) {
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        //密码错误
        if (!password.equals(user.getPassword())) {
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }
        //账号被锁定
        if (user.getStatus() == 0) {
            throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
        }

        //登录成功后，生成jwt令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.USER_ID, user.getId());
        claims.put(JwtClaimsConstant.USER_TYPE, user.getType());
        String token = JwtUtil.createJWT(
                jwtProperties.getAdminSecretKey(),
                jwtProperties.getAdminTtl(),
                claims);

        UserLoginVO userLoginVO = UserLoginVO.builder()
                .name(user.getName())
                .account(user.getAccount())
                .password(user.getPassword())
                .phone(user.getPhone())
                .sex(user.getSex())
                .balance(user.getBalance())
                .createTime(user.getCreateTime())
                .token(token)
                .build();

        return userLoginVO;
    }

    /**
     * 新增用户
     *
     * @param userDTO
     */
    public void insert(UserDTO userDTO) {
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        userMapper.insert(user);
    }

    /**
     * 用户分页查询
     *
     * @param userPageQueryDTO
     * @return
     */
    public PageResult page(UserPageQueryDTO userPageQueryDTO) {
        PageHelper.startPage(userPageQueryDTO.getPage(), userPageQueryDTO.getPageSize());
        Page<User> page = userMapper.pageQuery(userPageQueryDTO);
        return new PageResult(page.getTotal(), page.getResult());
    }

    /**
     * 根据id修改用户
     *
     * @param userDTO
     */
    public void update(UserDTO userDTO) {
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        userMapper.update(user);
    }

    /**
     * 用户启用禁用
     *
     * @param status
     * @param id
     */
    public void startOrStop(Integer status, Long id) {
        User user = User.builder()
                .id(id)
                .status(status)
                .build();

        userMapper.update(user);
    }

    /**
     * 修改密码
     *
     * @param passwordUpdateDTO
     */
    public void updatePassword(PasswordUpdateDTO passwordUpdateDTO) {
        Boolean isPasswordCorrect = userMapper.getByIdAndPassword(BaseContext.getCurrentId(), passwordUpdateDTO.getOldPassword());
        if (!isPasswordCorrect) {
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }

        User user = User.builder()
                .id(BaseContext.getCurrentId())
                .password(passwordUpdateDTO.getNewPassword())
                .build();
        userMapper.update(user);
    }

    /**
     * 创建账号
     *
     * @param userDTO
     */
    public void createAccount(UserDTO userDTO) {
        userDTO.setType(TypeConstant.USER);
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        userMapper.insert(user);

        userMapper.updateCreateUserAndUpdateUser(user.getId());
    }

    /**
     * 根据用户名和手机号查询用户
     *
     * @param account
     * @param phone
     * @return
     */
    public void getByAccountAndPhone(String account, String phone) {
        Boolean isUserExist = userMapper.getByAccountAndPhone(account, phone);
        if (!isUserExist) {
            throw new AccountOrPasswordErrorException(MessageConstant.ACCOUNT_OR_PHONE_ERROR);
        }
    }

    /**
     * 重置密码
     *
     * @param passwordUpdateDTO
     */
    public void resetPassword(PasswordUpdateDTO passwordUpdateDTO) {
        userMapper.updateByAccount(passwordUpdateDTO.getAccount(), passwordUpdateDTO.getNewPassword());
    }

    /**
     * 根据id查询用户
     *
     * @param id
     * @return
     */
    public User getById(Long id) {
        return userMapper.getById(id);
    }

    /**
     * 扣减余额
     *
     * @param id
     * @param amount
     */
    public void deductBalance(Long id, BigDecimal amount) {
        userMapper.deductBalance(id, amount);
    }
}
